<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>FSM 可视化编辑器 - @dao3fun/fsm</title>
    <link rel="stylesheet" href="style.css" />
    <!-- Cytoscape.js & cytoscape-dagre CDN -->
    <script src="https://unpkg.com/cytoscape@3.30.2/dist/cytoscape.min.js"></script>
    <script src="https://unpkg.com/dagre@0.8.5/dist/dagre.min.js"></script>
    <script src="https://unpkg.com/cytoscape-dagre@2.5.0/cytoscape-dagre.js"></script>
  </head>
  <body>
    <header class="app-header">
      <h1>
        FSM 可视化编辑器 -
        <span
          class="text-primary"
          style="cursor: pointer"
          onclick="window.open('https://www.npmjs.com/package/@dao3fun/fsm')"
          >@dao3fun/fsm</span
        >
      </h1>
      <div class="actions">
        <button id="btn-import-json">导入</button>
        <button id="btn-export-json">导出</button>
        <button id="btn-paste-config">以 TS 配置导入</button>
        <button id="btn-download-ts">下载 TS 文件</button>
        <button id="btn-reset">清空</button>
      </div>
    </header>

    <main class="container">
      <section class="left">
        <div class="panel">
          <h2>状态列表</h2>
          <ul id="state-list"></ul>
        </div>
        <div class="panel">
          <h2>事件列表</h2>
          <ul id="event-list"></ul>
        </div>

        <div class="panel">
          <h2>TypeScript 预览 <button id="btn-copy-ts">一键复制</button></h2>
          <textarea id="ts-preview" readonly></textarea>
        </div>
      </section>

      <section class="right">
        <div class="panel">
          <h2>图形预览</h2>
          <div id="graph"></div>
        </div>
      </section>
    </main>

    <template id="transition-form-template">
      <div class="transition-form">
        <label>
          源状态
          <select data-field="from"></select>
        </label>
        <label>
          事件
          <select data-field="event"></select>
        </label>
        <label>
          目标状态
          <select data-field="to"></select>
        </label>
      </div>
    </template>

    <!-- 右键菜单：节点操作 -->
    <div id="ctx-menu" style="display: none">
      <button id="ctx-add-state">新增状态</button>
      <button id="ctx-rename">重命名</button>
      <button id="ctx-add-transition">新增迁移</button>
      <button id="ctx-set-initial">设为初始</button>
      <button id="ctx-delete" class="danger">删除</button>
      <div class="ctx-sep"></div>
      <button id="ctx-edge-rename">重命名事件</button>
      <button id="ctx-edge-reverse">反转方向</button>
      <button id="ctx-edge-delete" class="danger">删除迁移</button>
      <div class="ctx-sep"></div>
      <div id="ctx-life">
        <div class="ctx-tip">生命周期（函数表达式）</div>
        <label class="field">
          <div class="field-label">onEnter</div>
          <textarea
            id="ctx-life-enter"
            placeholder="(_, motion) => { }"
          ></textarea>
        </label>
        <label class="field">
          <div class="field-label">onExit</div>
          <textarea
            id="ctx-life-exit"
            placeholder="(_, motion) => { }"
          ></textarea>
        </label>
        <label class="field">
          <div class="field-label">onUpdate</div>
          <textarea id="ctx-life-update" placeholder="(_) => { }"></textarea>
        </label>
        <div
          class="modal-actions"
          style="
            padding: 8px 0 0 0;
            display: flex;
            align-items: center;
            gap: 10px;
          "
        >
          <span id="ctx-life-status" style="font-size: 12px; color: #6b7280"
            >已开启自动保存</span
          >
        </div>
      </div>
    </div>

    <!-- 隐藏文件选择器：用于导入 JSON -->
    <input
      id="json-file"
      type="file"
      accept="application/json,.json"
      style="display: none"
    />

    <!-- 粘贴 Config 模态框 -->
    <div id="paste-modal" class="modal" style="display: none">
      <div class="modal-body">
        <h3>粘贴 MachineConfig 对象（可为 JSON 或 JS 对象字面量）</h3>
        <div class="tip">
          支持直接粘贴含函数的对象字面量，例如 onEnter: () =>
          {...}。建议在编辑器中撰写代码，这里仅做导入生成。
        </div>
        <textarea
          id="paste-text"
          placeholder="{ initial: 'idle', states: { idle: { on: { FETCH: 'loading' }, onEnter: () => {} } } }"
        ></textarea>
        <div class="modal-actions">
          <button id="btn-paste-import">导入</button>
          <button id="btn-paste-cancel">取消</button>
        </div>
      </div>
    </div>

    <!-- 新增迁移 模态框 -->
    <div id="add-trans-modal" class="modal" style="display: none">
      <div class="modal-body">
        <h3>新增迁移</h3>
        <div class="transition-form">
          <label>
            源状态
            <select id="trans-from"></select>
          </label>
          <label>
            事件
            <select id="trans-event"></select>
            <div class="field-help">
              如需新事件，请选择“自定义事件…”并在下方输入
            </div>
          </label>
          <div id="trans-new-event-wrap" style="display: none">
            <label>
              新事件名
              <input
                id="trans-new-event"
                type="text"
                placeholder="自定义事件名"
              />
            </label>
          </div>
          <label>
            目标状态
            <select id="trans-to"></select>
          </label>
        </div>
        <div class="trans-preview">
          <span id="trans-preview-text">（未选） -- （未选） --> （未选）</span>
        </div>
        <div class="modal-actions">
          <button id="btn-add-trans-ok">确定</button>
          <button id="btn-add-trans-cancel">取消</button>
        </div>
      </div>
    </div>

    <!-- 新增状态 模态框 -->
    <div id="add-state-modal" class="modal" style="display: none">
      <div class="modal-body">
        <h3>新增状态</h3>
        <input id="add-state-input" type="text" placeholder="例如：idle" />
        <div class="modal-actions">
          <button id="btn-add-state-ok">确定</button>
          <button id="btn-add-state-cancel">取消</button>
        </div>
      </div>
    </div>

    <!-- 重命名状态 模态框 -->
    <div id="rename-state-modal" class="modal" style="display: none">
      <div class="modal-body">
        <h3>重命名状态</h3>
        <input id="rename-state-input" type="text" />
        <div class="modal-actions">
          <button id="btn-rename-state-ok">确定</button>
          <button id="btn-rename-state-cancel">取消</button>
        </div>
      </div>
    </div>

    <!-- 重命名事件（单条迁移） 模态框 -->
    <div id="rename-event-modal" class="modal" style="display: none">
      <div class="modal-body">
        <h3>重命名事件</h3>
        <div class="tip" id="rename-event-tip"></div>
        <input id="rename-event-input" type="text" placeholder="新的事件名" />
        <div class="modal-actions">
          <button id="btn-rename-event-ok">确定</button>
          <button id="btn-rename-event-cancel">取消</button>
        </div>
      </div>
    </div>

    <script src="main.js"></script>
  </body>
</html>
